-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Don't build prop table during json_encode(JsonSerializable) #9703
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't build prop table during json_encode(JsonSerializable) #9703
Conversation
@TysonAndre, please check the failing ext/standard/tests/class_object/get_object_vars_variation_004.phpt; maybe only the test expection needs to be updated. |
Save memory and time by not building/updating the property table. When performing infinite recursion detection on objects, always check it on the object rather than its property table. This reduces the additional memory usage for both internal and userland implementations of JsonSerializable caused by json_encode. It does this by avoiding creating the properties table for the first time. (Classes such as SplFixedArray both implement JsonSerializable and override get_properties) This change also makes the method of infinite recursion detection consistent with the special case for standard classes from f9f8c1c
e7adcaf
to
0765e92
Compare
That's expected - var_dump was using the gc flags on the object to detect infinite recursion, and json_encode is now using the gc flags on the object to detect infinite recursion. The intent of get_object_vars_variation_004.phpt looks like it's to check that the right property fields are exported in get_object_vars, for properties with names that resemble protected/private properties that are not actually protected/private properties dd9ad09 I guess that this change would also mean that calling
If this or other refactorings in 8.3-dev affect major frameworks, there's the option to track infinite recursion for json_decode separately from var_export by using a different flag bit |
So this is actually not a new idea (read https://bugs.php.net/bug.php?id=81524 ). The problem is obviously that you break this (which I tried with your patch and it's really broken): class X implements JsonSerializable {
public $prop = "value";
public function jsonSerialize(): mixed {
var_dump($this);
return ['p' => $this->prop];
}
}
echo json_encode(new X()) Basically there are for sure users that use @nikic tried to handle it here #7589 but it was too slow. You could maybe try his suggestion in #7589 (comment) :
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As noted the var_dump($this)
inside jsonSerialize
needs to be supported.
I hadn't seen that before. I wasn't clear on the expected behavior for var_dump - you'd have similar issues with __debugInfo and var_export, but since there are users that want this I'll avoid merging this
I see that was also mentioned in a comment there. #7589 (comment) was discouraged since using a bit flag just for json seemed excessive That PR was using pointers as hash buckets directly, which leads to a lot of hash collisions (e.g. being aligned to 16 bytes in practice would mean all values would be hashed to the same |
This was addressed by 53aa53f |
Save memory and time by not building/updating the property table.
When performing infinite recursion detection on objects, always check it on the object rather than its property table.
This reduces the additional memory usage for both internal and userland implementations of JsonSerializable caused by json_encode. It does this by avoiding creating the properties table for the first time. (Classes such as SplFixedArray both implement JsonSerializable and override get_properties)
This change also makes the method of infinite recursion detection consistent with the special case for standard classes from
f9f8c1c
Also mentioned in #8046 (comment) - a similar change was already made to var_export/debug_zval_dump